﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NetMQ;
using NetMQ.Sockets;

namespace IMLibrary.ExZeroMQ
{
    /// <summary>
    /// MQClient
    /// </summary>
    public class  MQClient : IDisposable
    {
        #region 事件
        public delegate void ReceiveEventHandler(object sender, MQEventArgs e);

        public event ReceiveEventHandler Receive;

        private void OnReceive(MQEventArgs e)
        {
            if (Receive != null)
                Receive(this, e);
        }
        #endregion

        #region 字段
        private int _port;
        private NetMQSocket _socket;
        private ClientType _type;
        private string _ip;
        private bool _isRead=true;
        private Task _task;
        #endregion

        #region 属性
        public byte[] ClientID
        { set; get; }
        
        public NetMQSocket Socket
        {
            get { return _socket; }
        }
        #endregion

        #region 私有方法 
        private void AsyncRead(NetMQSocket cSocket)
        {
            while (_isRead)
            {
                try
                {
                    var msg = cSocket.ReceiveFrameBytes();
                    OnReceive(new MQEventArgs(msg));
                }
                catch { }
            }
        }
        #endregion

        #region 公共方法
        public void Connect(string serverIP, int port, ClientType type, string ClientId = "ClientId")
        {
            _type = type;
            _ip = serverIP;
            _port = port;
            ClientID = Encoding.UTF8.GetBytes(ClientId);

            switch (_type)
            {
                case ClientType.Request:
                    _socket = new RequestSocket();
                    break;
                case ClientType.Sub:
                    _socket = new SubscriberSocket();
                    break;
                case ClientType.Dealer:
                    _socket = new DealerSocket();
                    _socket.Options.Identity = ClientID;
                    break;
                case ClientType.Stream:
                    _socket = new StreamSocket();
                    break;
                case ClientType.Pull:
                    _socket = new PullSocket();
                    break;
                case ClientType.XSub:
                    _socket = new XSubscriberSocket();
                    break;
                default:
                    _socket = new RequestSocket();
                    break;
            }
            _socket.Connect("tcp://" + _ip + ":" + _port);
        }

        public void StartAsyncReceive()
        {
            if (_task == null)
                _task = Task.Factory.StartNew(() => AsyncRead(_socket), TaskCreationOptions.LongRunning);
        }

        /// <summary>
        /// 发送数据到服务器
        /// </summary>
        /// <param name="data"></param>
        public void Send(byte[] data)
        {
            if (_isRead)
            {
                _socket.TrySendFrame(data);
                //_socket.SendFrame(data);
            }
        }
 
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _isRead = false;
            //if (_task != null)
            //    _task.Dispose();
            _socket.Close(); 
            _socket.Dispose();
        }
        #endregion
    }
}
